package service;

import java.io.IOException;
import java.net.UnknownHostException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.jms.JMSException;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import tagger.StringHelper;
import tagger.VietnameseTagger;
import util.CategoryHelper;
import util.SocketContentHandle;
import util.TagHelper;

import model.CategoryModel;
import model.ImageModel;
import model.NewsModel;
import model.SubCategoryModel;
import model.TagModel;
import entity.Category;
import entity.News;
import entity.NewsImage;
import entity.SubCategory;
import entity.Tag;

public class ContentService {

	private static NewsModel newsModel = new NewsModel();
	private static TagModel tagModel = new TagModel();
	private static ImageModel imgModel = new ImageModel();
	private static CategoryModel cateModel = new CategoryModel();
	private static SubCategoryModel subModel = new SubCategoryModel();
	private static String site = "vnexpress.net";
	private static String[] splitString;
	private static ArrayList<String> tempArrayList;
	private static Document doc;
	private static Calendar cal;
	private static Elements tempElements;
	private static News n;
	private static Category cate;
	private static SubCategory sub;

	public static void getNewsFromUrl(String url) {

		n = newsModel.findByUrl(url);
		// n = newsModel.getFalseComplete();
		// n = new News();
		// n.setUrl(url);

		if (n != null && !n.getUrl().equalsIgnoreCase("")) {
			try {
				doc = SocketContentHandle.getSiteContentBySocket(site,
						n.getUrl());
			} catch (UnknownHostException ex) {
				System.out.println("Unknow error : ");
				ex.printStackTrace();
			} catch (IOException ex) {
				System.out.println("IO error : ");
				ex.printStackTrace();
			}
			// get news content.
			Elements content = doc.select("div[style=overflow:hidden]");
			if (content.size() > 0) {
				// remove flash page.
				if (content.select("#flashContent").size() > 0) {
					System.out
							.println("Url " + n.getUrl() + " is flash page !");
					newsModel.delete(n);
					return;
				}
				// remove page has many video.
				tempElements = content.select("a[href*=.asp]");
				if (tempElements.size() > 3) {
					System.out.println("Url " + n.getUrl()
							+ " has too many video !");
					newsModel.delete(n);
					return;
				}

				// get detail url inside page.
				new URLService(n.getUrl());

				// get title.
				String title = content.select(".Title").text();
				n.setTitle(title);
				n.setAlias(StringHelper.replaceVietnamese(title));
				content.select(".Title").remove();

				// get category, sub category and alias.
				n = getCategory(n);

				// get description and related link.
				tempElements = content.select(".Lead");
				n.setDescription(tempElements.first().html()
						.replaceAll("(<br)(.)*", "").replaceAll("<a[^>]+>", "")
						.replaceAll("<\\/[ ]*a>", ""));
				tempElements = tempElements.select("a");
				tempArrayList = new ArrayList<String>();
				for (Element relateUrl : tempElements) {
					tempArrayList.add("http://vnexpress.net"
							+ relateUrl.attr("href"));
				}
				n.setRelateUrls(tempArrayList);
				content.select(".Lead").remove();
				content.select("script").remove();

				// get images.
				content = getImage(content, n);

				// get content, remove all link.
				tempElements = Jsoup
						.parse("<div id=\"content\">" + content.html()
								+ "</div>").getElementById("content")
						.children();
				n.setAuthor(tempElements.select("p[align=right]").text());
				StringBuilder newsContent = new StringBuilder();
				for (int i = 0; i < tempElements.size(); i++) {
					if (tempElements.get(i).tagName().equalsIgnoreCase("p")) {
						if (tempElements.get(i).attr("align")
								.equalsIgnoreCase("right")) {
							continue;
						} else {
							newsContent.append("<p class=\"content\">"
									+ tempElements.get(i).html()
											.replaceAll("<a[^>]+>", "")
											.replaceAll("<\\/[ ]*a>", "")
									+ "</p>\n");
						}
					} else if (tempElements.get(i).tagName()
							.equalsIgnoreCase("table")) {
						if (tempElements.get(i).select("a").size() > 0) {
							tempElements.remove(i);
						} else {
							tempElements.get(i).attr("align", "center");
							newsContent.append(tempElements.get(i) + "\n");
						}
					}
				}
				n.setComplete(true);
				n.setContent(newsContent.toString());
				n.setStatus(1);

				// get tag and date.
				System.out.println("Nay thi content: ");
				System.out.println(n.getContent());
				n.setTagged(addTag(doc, n));
				n.setDoc(addDate(doc));
				cal = Calendar.getInstance();
				n.setDog(cal.getTime());

				// get other tag.
				n.setOtherTags(addOtherTag(n.getTagged()));

				newsModel.save(n);
				System.out.println("Url " + n.getUrl() + " saved success ! ");
			} else {
				newsModel.delete(n);
				System.out.println("Url " + n.getUrl() + " has no content !");
			}
		} else {
			newsModel.delete(n);
			System.out.println("News is not valid !");
			return;
		}

	}

	public static News getCategory(News n) {
		splitString = n.getUrl().replaceAll("http://", "").split("/");
		if (splitString.length == 6) {
			n.setCategory(splitString[2]);
			n.setSubCategory(splitString[2]);
			n.setAlias(splitString[5]);
		}
		if (splitString.length == 7) {
			n.setCategory(splitString[2]);
			n.setSubCategory(splitString[3]);
			n.setAlias(splitString[6]);
		}
		System.out.println(n.getCategory());
		System.out.println(n.getSubCategory());
		cate = cateModel.findByAlias(n.getCategory());
		sub = subModel.findByAlias(n.getSubCategory());

		// if have no category.
		if (cate == null || cate.getAlias().equalsIgnoreCase("")) {
			System.out.println("Chua co cate");
			cate = new Category();
			cate.setAlias(n.getCategory());
			cate.setTitle(CategoryHelper.getByAlias(cate.getAlias()));
			if (sub == null || sub.getAlias().equalsIgnoreCase("")) {
				System.out.println("Chua co sub : ");
				tempArrayList = new ArrayList<String>();
				tempArrayList.add(n.getSubCategory());
				cate.setSubCategory(tempArrayList);
				sub = new SubCategory();
				if (n.getSubCategory().equalsIgnoreCase(n.getCategory())) {
					sub.setTitle(CategoryHelper.getByAlias("tin-tuc-chung"));
				} else {
					sub.setTitle(CategoryHelper.getByAlias(n.getSubCategory()));
				}
				sub.setAlias(n.getSubCategory());
				cateModel.save(cate);
				subModel.save(sub);
			} else {
				System.out.println("Co roi, nhung trung -> add ca cate : ");
				sub = new SubCategory();
				if (n.getSubCategory().equalsIgnoreCase(n.getCategory())) {
					sub.setTitle(CategoryHelper.getByAlias("tin-tuc-chung"));
				} else {
					sub.setTitle(CategoryHelper.getByAlias(n.getSubCategory()));
				}
				sub.setAlias(sub.getAlias() + "-" + cate.getAlias());
				tempArrayList = new ArrayList<String>();
				tempArrayList.add(sub.getAlias());
				tempArrayList.addAll(cate.getSubCategory());
				cate.setSubCategory(tempArrayList);
				cateModel.save(cate);
				subModel.save(sub);
			}
			System.out.println("Cate Title : " + cate.getTitle());
			System.out.println("Cate Alias : " + cate.getAlias());
			System.out.println("Sub Title : " + sub.getTitle());
			System.out.println("Sub Alias : " + sub.getAlias());
		} else {
			System.out.println("Co cate roi : ");
			if (sub == null || sub.getAlias().equalsIgnoreCase("")) {
				System.out.println("Chua co sub : ");
				tempArrayList = new ArrayList<String>();
				tempArrayList.add(n.getSubCategory());
				tempArrayList.addAll(cate.getSubCategory());
				cate.setSubCategory(tempArrayList);
				sub = new SubCategory();
				if (n.getSubCategory().equalsIgnoreCase(n.getCategory())) {
					sub.setTitle(CategoryHelper.getByAlias("tin-tuc-chung"));
				} else {
					sub.setTitle(CategoryHelper.getByAlias(n.getSubCategory()));
				}
				sub.setAlias(n.getSubCategory());
				cateModel.save(cate);
				subModel.save(sub);
			} else {
				System.out.println("Co sub roi : ");
				// check if cate had this sub
				boolean hadSub = false;
				for (String obj : cate.getSubCategory()) {
					if (obj.equalsIgnoreCase(sub.getAlias())) {
						hadSub = true;
					}
				}
				// if cate had this sub. do nothing.

				// if cate have no this sub.
				if (!hadSub) {
					SubCategory subTemp = new SubCategory();
					subTemp.setAlias(sub.getAlias() + "-" + cate.getAlias());
					subTemp.setTitle(sub.getTitle());
					tempArrayList = new ArrayList<String>();
					tempArrayList.add(subTemp.getAlias());
					tempArrayList.addAll(cate.getSubCategory());
					cate.setSubCategory(tempArrayList);
					cateModel.save(cate);
					subModel.save(sub);
				}
			}
			System.out.println("Cate Title : " + cate.getTitle());
			System.out.println("Cate Alias : " + cate.getAlias());
			System.out.println("Sub Title : " + sub.getTitle());
			System.out.println("Sub Alias : " + sub.getAlias());
		}
		System.out.println("News Alias : " + n.getAlias());
		return n;
	}

	public static Elements getImage(Elements content, News n) {
		tempElements = content.select("img");
		int temp = 0;
		cal = Calendar.getInstance();
		NewsImage img;
		for (Element e : tempElements) {
			String imgLink = e.attr("src").toString();
			splitString = imgLink.split("/");
			String imgName = splitString[splitString.length - 1];
			imgName = imgName.replaceAll("%", "");
			imgName = (n.getAlias() + "_" + imgName).toLowerCase();
			img = new NewsImage();
			img.setUrl("http://vnexpress.net/" + imgLink);
			img.setName(imgName);
			img.setYear("" + cal.get(Calendar.YEAR));
			img.setMonth("" + cal.get(Calendar.MONTH) + 1);
			img.setDay("" + cal.get(Calendar.DATE));
			img.setStatus(1);
			imgModel.save(img);
			try {
				ActiveMQService.sendImageSMS(img.getUrl());
				System.out.println("send sms ok !");
			} catch (JMSException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}

			String regex = "img[src=" + imgLink + "]";
			try {
				String newImageSrc = "http://o2tv.vn:8080/" + "images_news/"
						+ img.getYear() + "/" + img.getMonth() + "/"
						+ img.getDay() + "/" + imgName;
				content.select(regex).attr("src", newImageSrc);
				if (temp == 0) {
					n.setImgDescription(newImageSrc);
					temp = 1;
				}
			} catch (Exception exception) {
				continue;
			}
		}
		return content;
	}

	public static ArrayList<String> addTag(Document doc, News n) {
		// your tag from your site
		System.out.println("Get Tag ===========");
		tempElements = doc.select(".tag-text");
		tempElements = tempElements.select("a");
		tempArrayList = new ArrayList<String>();
		TagModel tagModel = new TagModel();
		Tag tag;
		String alias;
		for (Element e : tempElements) {
			splitString = e.attr("href").split("/");
			alias = splitString[splitString.length - 1];
			tag = tagModel.findByAlias(alias);
			if (tag != null && !tag.getAlias().equalsIgnoreCase("")) {
				tag.setCount(tag.getCount() + 1);
				tagModel.save(tag);
			} else {
				tag = new Tag();
				tag.setAlias(alias);
				tag.setCount(1);
				tag.setTitle(e.text());
				tagModel.save(tag);
			}
			if (!tempArrayList.contains(alias)) {
				tempArrayList.add(alias);
			}
		}

		System.out.println("Get my tag =======");
		// my Tag born
		System.out.println(n.getContent());
		List<Tag> listTag = VietnameseTagger.tagFromHtml(n.getContent());
		Tag item;
		if (listTag.size() > 0) {
			for (int i = 0; i < listTag.size(); i++) {
				item = listTag.get(i);
				tag = tagModel.findByAlias(item.getAlias());
				if (tag != null && !tag.getAlias().equalsIgnoreCase("")) {
					tag.setCount(tag.getCount() + 1);
					tag.setTitle(item.getTitle());
					tagModel.save(tag);
				} else {
					item.setCount(1);
					tagModel.save(item);
				}
				System.out.println(item.getAlias());
				if (!tempArrayList.contains(item.getAlias())
						&& !item.getAlias().equalsIgnoreCase("")
						&& item.getAlias() != null) {
					tempArrayList.add(item.getAlias());
				}
			}
		}
		for (String tag2 : tempArrayList) {
			System.out.println(tag2);
		}
		System.out.println("Finish get tag");
		return tempArrayList;
	}

	public static ArrayList<String> addOtherTag(ArrayList<String> tagged) {
		System.out.println("adding--------------");
		tempArrayList = new ArrayList<String>();
		int count = 0;
		Tag tag;
		while (true) {
			count++;
			tag = tagModel.random();
			if (!tagged.contains(tag.getAlias()) && tag != null
					&& !tag.getAlias().equalsIgnoreCase("")) {
				tempArrayList.add(tag.getAlias());
				System.out.println("Other tag ---- " + tag.getAlias());
			}
			if (count == 40 || tempArrayList.size() == 20) {
				break;
			}
		}
		return tempArrayList;
	}

	public static Date addDate(Document doc) {
		System.out.println("Get date=====");
		try {
			tempElements = doc.select(".folder-header");
			splitString = tempElements.select(".fr").text().split(",");
			SimpleDateFormat dateFormat = new SimpleDateFormat("dd/mm/yyyy");
			Date convertedDate = dateFormat.parse(splitString[1].replaceAll(
					" ", ""));
			System.out.println(convertedDate);
			return convertedDate;
		} catch (ParseException ex) {
			return new Date();
		}
	}

	public static void main(String[] args) {
		ContentService
				.getNewsFromUrl("http://vnexpress.net/gl/van-hoa/2010/10/3ba2220f/");

	}
}
